package com.cmbyc.todolist.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cmbyc.todolist.VO.UpdateUserInfoQuery;
import com.cmbyc.todolist.VO.UserInfoVO;
import com.cmbyc.todolist.VO.UserShowVO;
import com.cmbyc.todolist.entity.UserInfo;
import com.cmbyc.todolist.mapper.UserInfoMapper;
import com.cmbyc.todolist.service.MailService;
import com.cmbyc.todolist.service.UserInfoService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmbyc.todolist.utils.CopyObjectUtil;
import com.cmbyc.todolist.utils.Result;
import com.cmbyc.todolist.utils.Token.TokenService;
import com.cmbyc.todolist.utils.Token.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Random;

/**
 * <p>
 * 用户信息表 服务实现类
 * </p>
 *
 * @author CYF
 * @since 2022-01-02
 */
@Service
@Slf4j
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {

    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private TokenService tokenService;

    @Resource
    private MailService mailService;

    @Override
    public UserInfo getUserByBId(String bid) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("b_id", bid);
        return userInfoMapper.selectOne(queryWrapper);
    }

    @Override
    public Result findUser(UserInfoVO userInfoVO) {
        if (userInfoVO == null)
            return Result.error().message("参数为空");
        UserInfo userInfo = new UserInfo();
        CopyObjectUtil.copyProperties(userInfoVO, userInfo, true);
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>(userInfo);
        Page<UserInfo> userPage = new Page<>(userInfoVO.getPageNum(), userInfoVO.getPageSize());
        IPage<UserInfo> userIPage = userInfoMapper.selectPage(userPage, queryWrapper);
        userIPage.setTotal(userInfoMapper.selectCount(queryWrapper));
        return Result.ok().data("userInfo", userIPage);
    }

    @Override
    public Result login(UserInfoVO userInfoVO, HttpServletResponse response, HttpServletRequest request) {
        if (userInfoVO == null)
            return Result.error().message("登录失败，参数为空");
        UserInfo userInfo = getUserByBId(userInfoVO.getbId());
        if (userInfo == null) {
            return Result.error().message("登录失败,用户不存在");
        }
        if (!userInfo.getUserPassword().equals(userInfoVO.getUserPassword())) {
            return Result.error().message("登录失败,密码错误");
        } else {
            String token = tokenService.getToken(userInfo);
            HttpSession session = request.getSession();
            session.setAttribute("todolist_token",token);
            session.setMaxInactiveInterval(60*60);
            Cookie cookie = new Cookie("todolist_token", token);
            cookie.setPath("/");
            response.addCookie(cookie);
            return Result.ok().data("todolist_token", token);
        }
    }

    @Override
    public Result logout(HttpServletResponse httpServletResponse, HttpServletRequest httpServletRequest) {
        Cookie cookie = new Cookie("todolist_token", "");
        cookie.setPath("/");
        cookie.setMaxAge(0);
        httpServletResponse.addCookie(cookie);
        HttpSession session = httpServletRequest.getSession();
        session.removeAttribute("todolist_token");
        return Result.ok().message("注销成功");
    }

    @Override
    public Result register(UserInfoVO userInfoVO) {
        if (userInfoVO == null)
            return Result.error().message("注册失败，参数为空");
        UserInfo userInfo = new UserInfo();
        CopyObjectUtil.copyProperties(userInfoVO, userInfo, true);
        if (userInfo.getbId() == null || userInfo.getbId().isEmpty()) {
            return Result.error().message("注册失败，业务ID为空");
        }
        if (getUserByBId(userInfo.getbId()) != null) {
            return Result.error().message("注册失败，业务ID已存在");
        }
        if (userInfo.getUserName() == null || userInfo.getUserName().isEmpty()) {
            return Result.error().message("注册失败，用户名为空");
        }
        if (userInfo.getUserPassword() == null || userInfo.getUserPassword().isEmpty()) {
            return Result.error().message("注册失败，密码为空");
        }
        if (userInfo.getEmail() == null || userInfo.getEmail().isEmpty()) {
            return Result.error().message("注册失败，邮箱为空");
        }
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getEmail, userInfoVO.getEmail());
        if (userInfoMapper.selectOne(queryWrapper) != null) {
            return Result.error().message("注册失败，邮箱已存在");
        }

        Result result = Result.ok().message("注册成功");
        try {
            userInfoMapper.insert(userInfo);
        } catch (DuplicateKeyException e) {
            result = Result.error().message("注册失败");
        }
        return result;
    }

    @Override
    public Result validationEmail(UserInfoVO userInfoVO,HttpServletRequest request) {
        if (userInfoVO == null)
            return Result.error().message("发送失败，参数为空");
        if (userInfoVO.getEmail() == null || userInfoVO.getEmail().isEmpty())
            return Result.error().message("发送失败,邮箱为空");
        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getEmail, userInfoVO.getEmail());
        if (userInfoMapper.selectOne(queryWrapper) == null) {
            return Result.error().message("发送失败，邮箱错误");
        }
        Random rand = new Random();
        int verificationCode = rand.nextInt(900000)+100000;
        HttpSession session = request.getSession();
        session.setAttribute("verificationCode",verificationCode);
        String[] strings=new String[1];
        strings[0]=userInfoVO.getEmail();
        mailService.sendSimpleMail(strings,"todolist 验证码","您的验证码为："+verificationCode);
        return Result.ok().data("verificationCode", verificationCode).message("认证邮件发送成功");
    }

    @Override
    public Result updatePassword(UserInfoVO userInfoVO,HttpServletRequest request) {
        HttpSession session = request.getSession();
        if(session.getAttribute("verificationCode") == null){
            return Result.error().message("修改失败");
        }
        String s=session.getAttribute("verificationCode").toString();
        int verificationCode = Integer.parseInt(s);
        if (userInfoVO == null)
            return Result.error().message("修改失败，参数为空");
        Integer code = userInfoVO.getVerificationCode();
        if (code == null) {
            return Result.error().message("修改失败，验证码错误");
        }
        if (code!=verificationCode) {
            return Result.error().message("修改失败，验证码错误");
        }

        LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserInfo::getEmail, userInfoVO.getEmail());

        UserInfo userInfo = new UserInfo();
        userInfo.setUserPassword(userInfoVO.getUserPassword());
        Result result = Result.ok().data("bId", userInfoMapper.selectOne(queryWrapper).getbId()).message("修改成功");
        try {
            userInfoMapper.update(userInfo, queryWrapper);
            session.removeAttribute("verificationCode");
        } catch (DuplicateKeyException e) {
            result = Result.error().message("修改失败");
        }
        return result;
    }

    @Override
    public UserShowVO userShow(String bId) {
        return userInfoMapper.selectUserShow(bId);
    }

    @Override
    public Result updateUserInfo(UpdateUserInfoQuery query) {
        if (null != query) {
            query.setBId(TokenUtil.getTokenUserBId());
            userInfoMapper.updateUserInfo(query);
            return Result.ok();
        }
       return Result.error();
    }
}
